#include "ConfigImpl.h"

#include <iterator>

namespace smartvoice {

KeyNode* OpenConfig(const char* file)
{
	KeyNodeImpl *root = new KeyNodeImpl();
	if (0 != root)
	{
		if (!root->LoadFromFile(file))
		{
			delete root;
			root = 0;
		}
	}
//	root->Dump();
	return root;
}

KeyNode* OpenMemoryConfig(const char* config)
{
	KeyNodeImpl *root = new KeyNodeImpl();
	if (0 != root)
	{
		if (!root->LoadFromMemory(config))
		{
			delete root;
			root = 0;
		}
	}
	return root;
}

KeyNode* NewConfig(const char* root_name)
{
	if (root_name == 0 || root_name[0] == '\0') {
		return new KeyNodeImpl();
	}
	else {
		return new KeyNodeImpl(root_name);	
	}	
}

bool SaveConfig(const KeyNode* node, const char* file)
{
	const KeyNodeImpl *root = dynamic_cast<const KeyNodeImpl*>(node);
	if (0 == root)
		return false;

	return root->SaveToFile(file);
}

bool SaveMemoryConfig(const KeyNode* node, char* memory, int& len)
{
	std::string temp;
	if (!SaveMemoryConfig(node, temp))
		return false;

	const int real_len = temp.size();
	if (len < real_len)
	{
		len = real_len;
		return false;
	}

	len = real_len;
	memcpy(memory, temp.c_str(), len);
	return true;
}

bool SaveMemoryConfig(const KeyNode* node, std::string &memory)
{
	const KeyNodeImpl *root = dynamic_cast<const KeyNodeImpl*>(node);
	if (0 == root)
		return false;

	return root->SaveToMemory(memory);
}

void CloseConfig(KeyNode* node)
{
	KeyNodeImpl *root = dynamic_cast<KeyNodeImpl*>(node);
	if (0 == root)
		return;
	delete root;
}

std::ostream& operator << (std::ostream& os, const KeyNode* node)
{
	const KeyNodeImpl *root = dynamic_cast<const KeyNodeImpl*>(node);
	if (0 == root)
		return os;

	root->SaveToOStream(os);
	return os;
}

std::istream& operator >> (std::istream& is, KeyNode* node)
{
	KeyNodeImpl *root = dynamic_cast<KeyNodeImpl*>(node);

	std::string buf((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());

	root->LoadFromMemory(buf.c_str());
	return is;
}

} // end namespace smartvoice

